import random
import string
import django_redis
from captcha.image import ImageCaptcha
import logging
from django.http import HttpResponse, JsonResponse
from django.views import View
from mg.utils.sendEmail import send_sms
import json

con = django_redis.get_redis_connection('verify_code')

# Create your views here.
class ImageCodeView(View):
    def get(self,request,uuid):
        '''
        获取图片验证码
        :param request:
        :param uuid:
        :return:
        '''

        # 生成四位随机验证码
        seed = string.digits # '0123456789'
        r = random.choices(seed,k=4) # ['7','5','3','4']
        img_str = ''.join(r) # '7534'
        
        # print("img_str:",img_str)
        
        # print("第一个uuid",uuid)
        
        # 根据生成的数字创建图片验证码资源
        imgCode = ImageCaptcha().generate(img_str)
        
        # print(imgCode)
        
        # 将img_str存入redis数据库中
        
        con.setex("%s"%uuid,60,img_str)
        
        # 返回资源
        return HttpResponse(imgCode,content_type='image/png')


class SmsCodeView(View):
    def get(self,request,phone):
        '''
        1、匹配并删除图形验证码
        2、发送短信验证码
        :param reuqest:
        :param phone:
        :return:
        '''
        # 1、获取请求参数（路径参数+查询字符串）
        imgcode_client = request.GET.get('imgcode','')
        uuid = request.GET.get('uuid','')
        
        # print(phone)
        # print(imgcode_client)
        # print(uuid)
        
        phone = phone.replace("/", "")
        uuid = uuid.replace("/","")
        
        # 2、校验参数(完整性判断)
        if not all([phone,imgcode_client,uuid]):
            return JsonResponse({'code':'4001','errormsg':'缺少必传参数'})
        # 3、获取服务器端生成的图片验证码
        
        # 获取is_send并且判断是否发送过于频繁
        is_send = con.get('is_send_%s'%phone)

        # 获取is_send并且判断是否发送过于频繁
        if is_send:
            return JsonResponse({'code': '4004', 'errormsg': '请求过于频繁'})
        
        imgcode_server = con.get("%s"%uuid)
        # print("imgcode_server:%s"%imgcode_server)
        
        # 4、匹配（非空判断/一致性判断）
        if imgcode_server is None:
            return JsonResponse({'code':'4002','errormsg':'验证码已过期'})
        
        if imgcode_client.lower() != imgcode_server.decode("utf-8").lower():
            return JsonResponse({'code':'4003','errormsg':'验证码输入错误'})
        
        # 5、删除图片验证码（避免用户恶意测试）
        try:
            con.delete("%s"%uuid)
        except Exception as e:
            # 将异常写入日志文件
            logging.error(e)
        
        # 6、生成短信验证码
        seed = string.digits
        r = random.choices(seed, k=6)
        smsCode = ''.join(r)
        
        print("短信验证码为：",smsCode)
        
        # 7、保存短信验证码到redis数据库中
        # con.setex("sms_%s"%phone,60,smsCode)
        # 将标记变量存入数据库
        # con.setex('is_send_%s'%phone,60,1)
        
        # 对多条请求数据的请求效率问题的解决
        # 创建redis管道
        pl = con.pipeline()
        # 将redis请求添加到队列
        pl.setex("sms_%s"%phone,60,smsCode)
        pl.setex('is_send_%s'%phone,60,1)
        pl.execute() # 执行
        
        # 8、发送短信验证码(生产实现，测试的时候，可以暂时注释掉)
        # print("准备开始发送验证码")
        # 将json字符串数据转成python的dict形式
        # ret = json.loads(send_sms(smsCode,phone))
        # print("已经发送验证码")

        # Celery异步发送短信验证码
        from mg.celery_tasks.sms.tasks import huyi_send_sms_code
        ret = huyi_send_sms_code.delay(phone, smsCode)

        if ret: # 执⾏⼀个任务就返回⼀个taskid 689e889c-a607-49f3-9777-248a8dcce310
            # print(ret,type(ret))
            return JsonResponse({'code': '200', 'errormsg': 'OK'})
        return JsonResponse({'code': '5001', 'errormsg': '发送短信验证码失败'})

        # 9、根据外部接口返回值响应前端结果
        # if ret.get("code")==2:
        #     return JsonResponse({'code':'200','errormsg':'OK'})
        # else:
        #     return JsonResponse({'code': '5001', 'errormsg': '验证码输入错误'})

        # return JsonResponse({'code': '200', 'errormsg': 'OK'})  # 默认实现这个，可以用于测试前端是否成功

class CheckSmsCodeView(View):
    def get(self,request,phone):
        '''
        用户注册短信验证码校验
        :param request:
        :param phone:
        :return:
        '''
        # 1、接收请求参数
        smsCode = request.GET.get('smscode','')
        # print("接收到输入的验证码为：",smsCode)
        
        # 2、校验参数
        if not all([smsCode,phone]):
            return JsonResponse({'code':'4001','errormsg':'缺少必传参数'})
        
        # 3、查询服务器端的短信验证码
        smsCode_server = con.get("sms_%s"%phone)
        
        # 4、匹配(非空判断、有效性判断)
        if smsCode_server is None:
            return JsonResponse({'code':'4002','errormsg':'验证码已过期'})
        
        smsCode_server = smsCode_server.decode("utf-8")
        if smsCode_server!=smsCode:
            return JsonResponse({'code': '4003', 'errormsg': '验证码输入错误'})
        
        # 5、响应结果
        return JsonResponse({'code': '200', 'errormsg': 'OK'})
    